const { INTENT_NO_CONTROL_OBJ, INTENT_RETURN_FAIL } = require("./IntentStack");
const { CreepBehavior } = require("./Overtick");
const { Util, COLOR } = require("./Util");

//基础导航
let NavigateTo = class NavigateTo extends CreepBehavior{
    static namespace(){
        return "CommonBehavior"
    }

    do(pos,options){
        //初始化默认值
        if(options.ignoreCreeps == undefined){
            options.ignoreCreeps = true;
        }

        this.options = options;
        this.stepCehckFail = 0;
        this.targetPos = pos;

        let creep = this.getCreep();
        if(creep == undefined){
            this.throwUp(INTENT_NO_CONTROL_OBJ);
            return;
        }
        if(creep.pos.x == this.targetPos.x
        && creep.pos.y == this.targetPos.y
        && creep.pos.roomName == this.targetPos.roomName){
            return;
        }
        this.path = this.getPath(this.targetPos,this.options);
    }

    getPath(pos,options){

        let creep = this.getCreep();
        if(creep == undefined){
            this.throw(INTENT_NO_CONTROL_OBJ);
            return [];
        }

        // 计算路径
        let path = creep.pos.findPathTo(pos,options);

        //加入一个初始位置
        path.unshift({
            x:creep.pos.x,
            y:creep.pos.y
        });

        return path;
    }

    exception(e){
        switch(e.code){
            case INTENT_NO_CONTROL_OBJ:
                e.printStackTrace(`找不到名为 ${this.getCreepName()} 的 Creep,无法进行导航`)
                return INTENT_RETURN_FAIL;
            default:
                e.printStackTrace(`${this.getCreepName()} 未处理的异常`)
                return INTENT_RETURN_FAIL;
        }
        
    }

    finished(){

        if(this.path == undefined){
            return;
        }

        let creep = this.getCreep();
        if(creep == undefined){
            this.throwUp(INTENT_NO_CONTROL_OBJ);
            return;
        }

        creep.room.visual.poly(this.path, {
            stroke: '#fff', 
            strokeWidth: .15,
            opacity: .2, 
            lineStyle: 'dashed'
        });//绘制移动路径
        creep.room.visual.line(creep.pos.x,creep.pos.y, this.targetPos.x,this.targetPos.y,{
            lineStyle: 'dashed'
        });

        if(creep.fatigue > 0){
            this.stop();
            return;
        }

        //继续移动，检查起点
        if(creep.pos.x == this.path[0].x
        && creep.pos.y == this.path[0].y){
            this.stepCehckFail = 0;
            this.path.shift();//完成上一步移动
            if(this.path.length == 0){
                if(creep.pos.x == this.targetPos.x
                    && creep.pos.y == this.targetPos.y
                    && creep.pos.roomName == this.targetPos.roomName){
                        return;//完成移动
                    }
        
                    //移动路径丢失，重试
                    //TODO
                    return;
            }
        }else{//上一个(this.path[0])move移动失败
            this.stepCehckFail++;
            if(this.stepCehckFail > 2){
                this.stepCehckFail = 0;
                if(this.navigateDiagnosis()){
                    this.finished();
                }else{
                    this.throwUp(`UnreachableTarget`);
                }
                return;
            }
        }

        

        this.move(this.path[0].direction);
    }

    navigateDiagnosis(){

        let creep = this.getCreep();
        if(creep == undefined){
            return false;
        }

        if(this.path.length == 0){
            return false;
        }

        //检查原因
        let data = creep.room.lookAt(this.path[0].x,this.path[0].y);

        if(this.hasCreep(data)){//被creep挡住了
            //向路径后方creep点进行遍历忽略
            while(this.hasCreep(creep.room.lookAt(this.path[0].x,this.path[0].y))){
                this.path.shift();
                if(this.path.length == 0){
                    this.path.push({
                        x:this.targetPos.x,
                        y:this.targetPos.y,
                    })
                    break;
                }
            }

            //缓存剩余路径
            let leftPath = [].concat(this.path);

            let insertEndOfPath = new RoomPosition(leftPath[0].x,leftPath[0].y,creep.pos.roomName);

            //确保不能忽略creep
            this.options.ignoreCreeps = false;
            if(leftPath.length > 1){//导航终点
                this.options.range = 0;
            }
            let insertPath = this.getPath(insertEndOfPath,this.options);
            creep.room.visual.poly(insertPath, {stroke: '#ffc107', strokeWidth: .15,
                opacity: .2, lineStyle: 'dashed'});//绘制移动路径

            //连接原来的路线
            leftPath.shift();//注意要更改插入导航点的末端
            this.path = insertPath.concat(leftPath);
            return true;
        }

    }

    hasCreep(lookAtData){
        for(let i of lookAtData){
            if(i.type == 'creep'){
                return true;
            }
        }

        return false;
    }


}
// module.exports.NavigateToTest = NavigateToTest;

/**
 * 生产一个Creep
 */
let SpawnCreep = class SpawnCreep extends CreepBehavior{
    static namespace(){
        return "CommonBehavior";
    }

    do(spawn,body,options){

        let SpawnListen = class SpawnListen extends CreepBehavior{
            finished(){
                if(Game.creeps[this.getCreepName()] == undefined){
                    let result = spawn.spawnCreep(body,this.getCreepName(),options);
                    if(result == ERR_NOT_ENOUGH_ENERGY){
                        body = [WORK,CARRY,MOVE]
                    }
                    this.stop(1);
                    return;
                }

                if(Game.creeps[this.getCreepName()] != undefined
                && Game.creeps[this.getCreepName()].spawning == false){
                    return;
                }else{
                    this.stop(1);
                }
            }
        }
        this.todo(SpawnListen);
    }

    exception(e){
        switch(e.code){
            default:
                e.printStackTrace(`${this.getCreepName()} 未处理的异常`);
                return INTENT_RETURN_FAIL;
        }
    }

    finished(){
        if(Game.creeps[this.getCreepName()] != undefined
        && Game.creeps[this.getCreepName()].spawning == false){
            return;
        }
    }
}

//填充建筑
let FullStructure = class FullStructure extends CreepBehavior{
    do(target,type,amount){
        this.todo(NavigateTo,target.pos,{range:1});
        this.transfer(target,type,amount);
    }

    exception(e){
        switch(e.code){
            default:
                e.printStackTrace(`${this.getCreepName()} 未处理的异常`);
                return INTENT_RETURN_FAIL;
        }
    }

    finished(){
    }
}

//从Sorce采集能量
let HarvestEnergy = class HarvestEnergy extends CreepBehavior{
    do(target){
        this.todo(NavigateTo,target.pos,{
            range:1
        });

        let targetid = target.id;

        let FullHarvestCheck = class FullHarvestCheck extends CreepBehavior{
            finished(){
                let creep = this.getCreep();
                if(creep == undefined){
                    console.log("throw Up!");
                    this.throwUp(INTENT_NO_CONTROL_OBJ);
                    return;
                }
                if(creep.store[RESOURCE_ENERGY] < creep.store.getCapacity()){
                    this.harvest(new Source(targetid));
                }
            }

            exception(e){
                switch(e.code){
                    case INTENT_NO_CONTROL_OBJ:
                        Util.log(`${this.getCreepName()} 找不到`,{
                            color:COLOR.YELLOW
                        })
                        return INTENT_RETURN_FAIL;
                    default:
                        e.printStackTrace(`${this.getCreepName()} 未处理的异常`);
                        return INTENT_RETURN_FAIL;
                }
            }
        }

        this.todo(FullHarvestCheck)
    }

    exception(e){
        switch(e.code){
            default:
                e.printStackTrace(`${this.getCreepName()} 未处理的异常`);
                return INTENT_RETURN_FAIL;
        }
    }

    finished(){

    }
}

//升级
let FullUpgradeController = class FullUpgradeController extends CreepBehavior{
    do(target){
        this.targetController = target;
        this.todo(NavigateTo,target.pos,{range:3});
    }

    finished(){
        let creep = this.getCreep();
        if(creep == undefined){
            this.throw(INTENT_NO_CONTROL_OBJ);
            return;
        }
        if(creep.store[RESOURCE_ENERGY] > 0){
            this.upgradeController(this.targetController);
        }
    }

    exception(e){
        switch(e.code){
            default:
                e.printStackTrace(`${this.getCreepName()} 未处理的异常`);
                return INTENT_RETURN_FAIL;
        }
    }
}

//修复
let FullRepair = class FullRepair extends CreepBehavior{
    do(target){
        if(target.hits == target.hitsMax){
            return;
        }

        this.repairTargetId = target.id;
        this.todo(NavigateTo,target.pos,{range:3});
    }

    finished(){
        let creep = this.getCreep();
        if(creep == undefined){
            this.throwUp(INTENT_NO_CONTROL_OBJ);
            return;
        }
        let target = Game.getObjectById(this.repairTargetId);
        if(creep.store[RESOURCE_ENERGY] > 0){
            if(target.hits == target.hitsMax){
                return;
            }
            this.repair(target);
        }
    }

    exception(e){
        switch(e.code){
            default:
                e.printStackTrace(`${this,this.getCreepName()} 未处理的异常`);
                return;
        }
    }
}

let FullBuild = class FullBuild extends CreepBehavior{
    do(target){
        this.buildTargetId = target.id;
        this.todo(NavigateTo,target.pos,{range:3});
    }

    exception(e){
        switch(e.code){
            default:
                e.printStackTrace(`${this.getCreepName()} 未处理的异常`);
                return INTENT_RETURN_FAIL;
        }
    }

    finished(){
        let creep = this.getCreep();
        if(creep == undefined){
            this.throwUp(INTENT_NO_CONTROL_OBJ);
            return;
        }
        let target = Game.getObjectById(this.buildTargetId);

        if(target == null){
            return;
        }

        if(creep.store[RESOURCE_ENERGY] > 0){
            this.build(target);
        }
    }
}

module.exports.NavigateTo = NavigateTo;
module.exports.SpawnCreep = SpawnCreep;
module.exports.FullStructure = FullStructure;
module.exports.HarvestEnergy = HarvestEnergy;
module.exports.FullUpgradeController = FullUpgradeController;
module.exports.FullRepair = FullRepair;
module.exports.FullBuild = FullBuild;


//尝试获取能量

// let room = Game.creeps.Tom.room;
// room.lookAtArea(
//     0,0,
//     2,2,false);
// let sources = room.find(FIND_SOURCES);
// //处理参数
// let data = Util.analysisData(sources,function(source){
//     //计算剩余工位数量

//     //获取3*3地形
//     let pos = source.pos;
//     let startTime = Game.cpu.getUsed();
//     let area = room.lookAtArea(
//         pos.y-1,pos.x-1,
//         pos.y+1,pos.x+1,false);
//     console.log(Game.cpu.getUsed() - startTime + `${source.pos.x}`);
//     let availables = [];
//     for(let y in area){
//         for(let x in area[y]){
//             let contents = area[y][x];
//             let isPlace = false;
//             let hasCreep = false;
//             for(let content of contents){
//                 if(content.type == 'creep'){
//                     hasCreep = true;
//                     break;
//                 }

//                 if(content.type == 'terrain' && content.terrain != "wall"){
//                     isPlace = true;
//                     break;
//                 }
//             }

//             if(isPlace && (!hasCreep)){
//                 availables.push({
//                     x:x,
//                     y:y
//                 });
//             }
//         }
//     }

//     return{
//         target:source,
//         availables:availables
//     }
// })

// console.log(JSON.stringify(data))
